package secondriver.heathfood.common;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.widget.ImageView;
import secondriver.heathfood.client.Constants;
import secondriver.heathfood.util.LogUtil;
import secondriver.heathfood.util.SimpleDiskCache;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;

/**
 * Author : secondriver
 * Date :  2015/11/11
 */
public class NewLoadNetImageTask extends AsyncTask<String, Void, Bitmap> {

    private final LogUtil logUtil = LogUtil.getLogger(NewLoadNetImageTask.class.getName());

    private SimpleDiskCache simpleDiskCache;

    private WeakReference<ImageView> imageViewWeakReference;

    private String imageUrl;
    private String cacheFileName;

    public NewLoadNetImageTask(SimpleDiskCache simpleDiskCache, ImageView imageView) {
        this.simpleDiskCache = simpleDiskCache;
        this.imageViewWeakReference = new WeakReference<>(imageView);
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        logUtil.info("doInBackground load net images .");
        if (null == params || params.length != 2) {
            return null;
        }
        imageUrl = params[0]; //图片URl
        if (TextUtils.isEmpty(imageUrl)) {
            return null;
        }
        cacheFileName = params[1]; //图片缓存文件名

        Bitmap bitmap = null;
        InputStream inputStream = null;
        try {
            inputStream = new java.net.URL(imageUrl).openStream();
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(inputStream, null, opts);
            if (null != inputStream) {
                inputStream.close();
            }
            int width = opts.outWidth;
            int height = opts.outHeight;

            int inSampleSize = 1;
            if (height > Constants.IMAGE_MAX_WIDTH || width > Constants.IMAGE_MAX_HEIGHT) {
                final int halfHeight = height / 2;
                final int halfWidth = width / 2;
                // Calculate the largest inSampleSize value that is a power of 2 and keeps both
                // height and width larger than the requested height and width.
                while ((halfHeight / inSampleSize) > Constants.IMAGE_MAX_HEIGHT
                        && (halfWidth / inSampleSize) > Constants.IMAGE_MAX_WIDTH) {
                    inSampleSize *= 2;
                }
            }
            opts.inSampleSize = inSampleSize;
            opts.inJustDecodeBounds = false;
            inputStream = new java.net.URL(imageUrl).openStream();
            bitmap = BitmapFactory.decodeStream(inputStream, null, opts);
            logUtil.info("Load Image from net %s.", imageUrl);
        } catch (OutOfMemoryError error) {
            logUtil.warn("doInBackground load net images occur OutOfMemoryError.");
        } catch (IOException e) {
            logUtil.error("doInBackground load net images error .", e.getCause());
        } finally {
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        //  执行完成之后
        if (isCancelled()) {
            bitmap = null;
        }
        if (null != imageViewWeakReference && null != bitmap) {
            final ImageView imageView = imageViewWeakReference.get();
            final NewLoadNetImageTask task = getNewLoadNetImageTask(imageView);
            if (this == task && null != imageView) {
                imageView.setImageBitmap(bitmap);
            }
            if (null != simpleDiskCache && !TextUtils.isEmpty(cacheFileName)) {
                simpleDiskCache.putBitmapToCache(bitmap, cacheFileName, imageUrl);
            }
        }
    }

    public static class AsyncDrawable extends BitmapDrawable {

        private WeakReference<NewLoadNetImageTask> taskWeakReference;

        public AsyncDrawable(Resources resources, Bitmap bitmap, NewLoadNetImageTask task) {
            super(resources, bitmap);
            this.taskWeakReference = new WeakReference<>(task);
        }

        public NewLoadNetImageTask getNewLoadNetImageTask() {
            return this.taskWeakReference.get();
        }
    }

    private static NewLoadNetImageTask getNewLoadNetImageTask(ImageView imageView) {
        if (imageView != null) {
            final Drawable drawable = imageView.getDrawable();
            if (drawable instanceof AsyncDrawable) {
                final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
                return asyncDrawable.getNewLoadNetImageTask();
            }
        }
        return null;
    }

    public static boolean cancelNewNetLoadImageTask(String newImageUrl, ImageView imageView) {
        final NewLoadNetImageTask task = getNewLoadNetImageTask(imageView);
        if (task != null) {
            final String oldImageUrl = task.imageUrl;
            // If oldImageUrl is not yet set or it differs from the new data
            if (oldImageUrl == null || !oldImageUrl.equals(newImageUrl)) {
                // Cancel previous task
                task.cancel(true);
            } else {
                // The same work is already in progress
                return false;
            }
        }
        // No task associated with the ImageView, or an existing task was cancelled
        return true;
    }
}
